<!DOCTYPE html>
<html lang="zh-CN">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width,initial-scale=1">
    <title>第四章 变量、作用域和内存问题 | 我的世界</title>
    <meta name="generator" content="VuePress 1.8.2">
    <link rel="icon" href="/notes/favicon.ico">
    <link rel="manifest" href="/notes/manifest.json">
    <meta name="description" content="学习，生活，还有美食~">
    
    <link rel="preload" href="/notes/assets/css/0.styles.8453c794.css" as="style"><link rel="preload" href="/notes/assets/js/app.f19b5e39.js" as="script"><link rel="preload" href="/notes/assets/js/2.69392339.js" as="script"><link rel="preload" href="/notes/assets/js/18.7dffee3a.js" as="script"><link rel="preload" href="/notes/assets/js/14.e376f3f7.js" as="script"><link rel="prefetch" href="/notes/assets/js/10.4748ef2e.js"><link rel="prefetch" href="/notes/assets/js/11.4ec67c3b.js"><link rel="prefetch" href="/notes/assets/js/12.db234a0a.js"><link rel="prefetch" href="/notes/assets/js/13.0bdeeeea.js"><link rel="prefetch" href="/notes/assets/js/15.873f63d0.js"><link rel="prefetch" href="/notes/assets/js/16.6d650151.js"><link rel="prefetch" href="/notes/assets/js/17.f0bcb5c9.js"><link rel="prefetch" href="/notes/assets/js/19.5f0252c4.js"><link rel="prefetch" href="/notes/assets/js/20.abea2681.js"><link rel="prefetch" href="/notes/assets/js/21.252713aa.js"><link rel="prefetch" href="/notes/assets/js/22.c99488d0.js"><link rel="prefetch" href="/notes/assets/js/23.3839292f.js"><link rel="prefetch" href="/notes/assets/js/24.9cc2f325.js"><link rel="prefetch" href="/notes/assets/js/25.e9dcd2f1.js"><link rel="prefetch" href="/notes/assets/js/26.31898ae6.js"><link rel="prefetch" href="/notes/assets/js/27.88db2371.js"><link rel="prefetch" href="/notes/assets/js/28.2d29c56c.js"><link rel="prefetch" href="/notes/assets/js/29.a0b42251.js"><link rel="prefetch" href="/notes/assets/js/3.48b2b659.js"><link rel="prefetch" href="/notes/assets/js/30.9b38a2bb.js"><link rel="prefetch" href="/notes/assets/js/31.d374da8e.js"><link rel="prefetch" href="/notes/assets/js/32.7868c3f3.js"><link rel="prefetch" href="/notes/assets/js/33.87730e15.js"><link rel="prefetch" href="/notes/assets/js/34.5a5b6c6e.js"><link rel="prefetch" href="/notes/assets/js/35.1deedbd4.js"><link rel="prefetch" href="/notes/assets/js/36.d39f2b24.js"><link rel="prefetch" href="/notes/assets/js/37.d87637b4.js"><link rel="prefetch" href="/notes/assets/js/38.d118907c.js"><link rel="prefetch" href="/notes/assets/js/39.9f2c8514.js"><link rel="prefetch" href="/notes/assets/js/4.161aee82.js"><link rel="prefetch" href="/notes/assets/js/40.917feb30.js"><link rel="prefetch" href="/notes/assets/js/41.78e1b969.js"><link rel="prefetch" href="/notes/assets/js/42.cd6ac9d4.js"><link rel="prefetch" href="/notes/assets/js/43.961a438d.js"><link rel="prefetch" href="/notes/assets/js/44.ef1661d7.js"><link rel="prefetch" href="/notes/assets/js/45.b89cd059.js"><link rel="prefetch" href="/notes/assets/js/46.8ca9e560.js"><link rel="prefetch" href="/notes/assets/js/47.a35bec74.js"><link rel="prefetch" href="/notes/assets/js/48.953bb15e.js"><link rel="prefetch" href="/notes/assets/js/49.ae614c87.js"><link rel="prefetch" href="/notes/assets/js/5.ef4783db.js"><link rel="prefetch" href="/notes/assets/js/50.a9fbc190.js"><link rel="prefetch" href="/notes/assets/js/51.12ae367b.js"><link rel="prefetch" href="/notes/assets/js/52.57a5efe4.js"><link rel="prefetch" href="/notes/assets/js/53.861eb65b.js"><link rel="prefetch" href="/notes/assets/js/54.3bc1c9a1.js"><link rel="prefetch" href="/notes/assets/js/55.f724b26c.js"><link rel="prefetch" href="/notes/assets/js/56.02e48e7a.js"><link rel="prefetch" href="/notes/assets/js/6.72ed1ea6.js"><link rel="prefetch" href="/notes/assets/js/7.f1e39dec.js"><link rel="prefetch" href="/notes/assets/js/8.84b75613.js"><link rel="prefetch" href="/notes/assets/js/9.e1cd5390.js">
    <link rel="stylesheet" href="/notes/assets/css/0.styles.8453c794.css">
  </head>
  <body>
    <div id="app" data-server-rendered="true"><div class="theme-container"><header class="navbar"><div class="sidebar-button"><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" role="img" viewBox="0 0 448 512" class="icon"><path fill="currentColor" d="M436 124H12c-6.627 0-12-5.373-12-12V80c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12zm0 160H12c-6.627 0-12-5.373-12-12v-32c0-6.627 5.373-12 12-12h424c6.627 0 12 5.373 12 12v32c0 6.627-5.373 12-12 12z"></path></svg></div> <a href="/notes/" class="home-link router-link-active"><img src="/notes/images/fish.gif" alt="我的世界" class="logo"> <span class="site-name can-hide">我的世界</span></a> <div class="links"><div class="search-box"><input aria-label="Search" autocomplete="off" spellcheck="false" value=""> <!----></div> <nav class="nav-links can-hide"><div class="nav-item"><a href="/notes/notes/" class="nav-link router-link-active">🎓 学习</a></div><div class="nav-item"><a href="/notes/life/" class="nav-link">🏸 生活</a></div> <a href="https://gitee.com/zgj6" target="_blank" rel="noopener noreferrer" class="repo-link">
    git
    <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav></div></header> <div class="sidebar-mask"></div> <aside class="sidebar"><nav class="nav-links"><div class="nav-item"><a href="/notes/notes/" class="nav-link router-link-active">🎓 学习</a></div><div class="nav-item"><a href="/notes/life/" class="nav-link">🏸 生活</a></div> <a href="https://gitee.com/zgj6" target="_blank" rel="noopener noreferrer" class="repo-link">
    git
    <span><svg xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" x="0px" y="0px" viewBox="0 0 100 100" width="15" height="15" class="icon outbound"><path fill="currentColor" d="M18.8,85.1h56l0,0c2.2,0,4-1.8,4-4v-32h-8v28h-48v-48h28v-8h-32l0,0c-2.2,0-4,1.8-4,4v56C14.8,83.3,16.6,85.1,18.8,85.1z"></path> <polygon fill="currentColor" points="45.7,48.7 51.3,54.3 77.2,28.5 77.2,37.2 85.2,37.2 85.2,14.9 62.8,14.9 62.8,22.9 71.5,22.9"></polygon></svg> <span class="sr-only">(opens new window)</span></span></a></nav>  <ul class="sidebar-links"><li><section class="sidebar-group collapsable depth-0"><p title="学习笔记" class="sidebar-heading"><span>学习笔记</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p title="JavaScript 高程笔记" class="sidebar-heading open"><span>JavaScript 高程笔记</span> <span class="arrow down"></span></p> <ul class="sidebar-links sidebar-group-items"><li><a href="/notes/notes/pro-js-for-web-dev-note/" aria-current="page" title="JavaScript 高级程序设计 · 笔记" class="sidebar-link">JavaScript 高级程序设计 · 笔记</a></li><li><a href="/notes/notes/pro-js-for-web-dev-note/chapter01.html" title="第一章 JavaScript简介" class="sidebar-link">第一章 JavaScript简介</a></li><li><a href="/notes/notes/pro-js-for-web-dev-note/chapter02.html" title="第二章 在HTML中使用JavaScript" class="sidebar-link">第二章 在HTML中使用JavaScript</a></li><li><a href="/notes/notes/pro-js-for-web-dev-note/chapter03.html" title="第3章 基本概念" class="sidebar-link">第3章 基本概念</a></li><li><a href="/notes/notes/pro-js-for-web-dev-note/chapter04.html" aria-current="page" title="第四章 变量、作用域和内存问题" class="active sidebar-link">第四章 变量、作用域和内存问题</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/notes/notes/pro-js-for-web-dev-note/chapter04.html#基本类型和引用类型的值" title="基本类型和引用类型的值" class="sidebar-link">基本类型和引用类型的值</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/notes/notes/pro-js-for-web-dev-note/chapter04.html#复制变量值" title="复制变量值" class="sidebar-link">复制变量值</a></li><li class="sidebar-sub-header"><a href="/notes/notes/pro-js-for-web-dev-note/chapter04.html#传递参数" title="传递参数" class="sidebar-link">传递参数</a></li><li class="sidebar-sub-header"><a href="/notes/notes/pro-js-for-web-dev-note/chapter04.html#检测类型" title="检测类型" class="sidebar-link">检测类型</a></li></ul></li><li class="sidebar-sub-header"><a href="/notes/notes/pro-js-for-web-dev-note/chapter04.html#执行环境及作用域" title="执行环境及作用域" class="sidebar-link">执行环境及作用域</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/notes/notes/pro-js-for-web-dev-note/chapter04.html#没有块级作用域" title="没有块级作用域！" class="sidebar-link">没有块级作用域！</a></li></ul></li><li class="sidebar-sub-header"><a href="/notes/notes/pro-js-for-web-dev-note/chapter04.html#垃圾收集" title="垃圾收集" class="sidebar-link">垃圾收集</a><ul class="sidebar-sub-headers"><li class="sidebar-sub-header"><a href="/notes/notes/pro-js-for-web-dev-note/chapter04.html#标记清除" title="标记清除" class="sidebar-link">标记清除</a></li><li class="sidebar-sub-header"><a href="/notes/notes/pro-js-for-web-dev-note/chapter04.html#引用计数" title="引用计数" class="sidebar-link">引用计数</a></li><li class="sidebar-sub-header"><a href="/notes/notes/pro-js-for-web-dev-note/chapter04.html#管理内存" title="管理内存" class="sidebar-link">管理内存</a></li></ul></li></ul></li><li><a href="/notes/notes/pro-js-for-web-dev-note/chapter05.html" title="引用类型" class="sidebar-link">引用类型</a></li><li><a href="/notes/notes/pro-js-for-web-dev-note/chapter06.html" title="面向对象的程序设计" class="sidebar-link">面向对象的程序设计</a></li></ul></section></li><li><section class="sidebar-group collapsable depth-0"><p title="HTTP" class="sidebar-heading"><span>HTTP</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p title="微信小程序" class="sidebar-heading"><span>微信小程序</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p title="TS" class="sidebar-heading"><span>TS</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p title="Vite" class="sidebar-heading"><span>Vite</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p title="interviewquestion" class="sidebar-heading"><span>interviewquestion</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p title="AI" class="sidebar-heading"><span>AI</span> <span class="arrow right"></span></p> <!----></section></li><li><section class="sidebar-group collapsable depth-0"><p title="UE" class="sidebar-heading"><span>UE</span> <span class="arrow right"></span></p> <!----></section></li></ul> </aside> <main class="page"> <div class="theme-default-content content__default"><h1 id="第四章-变量、作用域和内存问题"><a href="#第四章-变量、作用域和内存问题" class="header-anchor">#</a> 第四章 变量、作用域和内存问题</h1> <h2 id="基本类型和引用类型的值"><a href="#基本类型和引用类型的值" class="header-anchor">#</a> 基本类型和引用类型的值</h2> <ul><li>基本类型指的是简单的数据段（即5种基本数据类型：Number,String,Boolean,Null,Undefined）。</li> <li>引用类型值指的是那些可能由多个值构成的对象（Object）。</li> <li>JavaScript不允许直接访问内存中的位置，因此在操作对象时，实际上在操作对象的引用。</li> <li>不能给基本类型的值添加属性，否则这个添加的属性值是undefined。只能给引用类型的值动态的添加属性。</li></ul> <p>基本类型值在内存中占据固定大小的空间，因此被保存在<strong>栈内存</strong>中；引用类型的值是对象，保存在<strong>堆内存</strong>中。</p> <h3 id="复制变量值"><a href="#复制变量值" class="header-anchor">#</a> 复制变量值</h3> <p>下面的例子可以说明，如果从一个变量向另一个变量复制基本类型的值，会在变量对象上创建一个新值，然后把该值复制
到为新变量分配的位置上。</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> num1 <span class="token operator">=</span> <span class="token number">5</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> num2 <span class="token operator">=</span> num1<span class="token punctuation">;</span>

console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'num1='</span><span class="token operator">+</span>num1<span class="token operator">+</span><span class="token string">', num2='</span><span class="token operator">+</span>num2<span class="token punctuation">)</span><span class="token punctuation">;</span>   <span class="token comment">// num1=5, num2=5</span>

num1 <span class="token operator">=</span> <span class="token number">6</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token string">'num1='</span><span class="token operator">+</span>num1<span class="token operator">+</span><span class="token string">', num2='</span><span class="token operator">+</span>num2<span class="token punctuation">)</span><span class="token punctuation">;</span>   <span class="token comment">// num1=6, num2=5</span>
</code></pre></div><p>复制对象时，其实复制的是对象的引用，修改原来的对象值会改变复制后的对象值。</p> <p><img src="/notes/assets/img/img4-2.32038866.png" alt="image"></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> obj1 <span class="token operator">=</span> <span class="token punctuation">{</span>name<span class="token operator">:</span><span class="token string">'原始的字符串'</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> obj2 <span class="token operator">=</span> obj1<span class="token punctuation">;</span>

console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj2<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>     <span class="token comment">// 原始的字符串</span>

obj1<span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">'修改一下'</span><span class="token punctuation">;</span>

console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj2<span class="token punctuation">.</span>name<span class="token punctuation">)</span><span class="token punctuation">;</span>     <span class="token comment">// 修改一下</span>
</code></pre></div><h3 id="传递参数"><a href="#传递参数" class="header-anchor">#</a> 传递参数</h3> <ul><li>ECMAScript 中所有函数的参数都是按值传递的。但对于对象就没那么简单了：
<ul><li>在向参数传递<strong>基本类型</strong>的值时，被传递的<strong>值</strong>会被复制给一个局部变量。</li> <li>在向参数传递<strong>引用类型</strong>的值时，会把这个值在内存中的<strong>地址</strong>复制给一个局部变量，因此这个局部变量的变化会反映在函数的外部。</li></ul></li></ul> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> obj1 <span class="token operator">=</span> <span class="token punctuation">{</span>name<span class="token operator">:</span><span class="token string">'name1'</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">function</span> <span class="token function">setName</span><span class="token punctuation">(</span><span class="token parameter">obj</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  obj<span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">'name2'</span><span class="token punctuation">;</span>
    <span class="token comment">// obj 和 obj1 引用的是同一个对象。换句话说，即使这个变量是按值传递的，obj 也会按引用来访问同一个对象。</span>
<span class="token punctuation">}</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj1<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// name1</span>
<span class="token function">setName</span><span class="token punctuation">(</span>obj1<span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj1<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// name2, 这种情况下原来对象的内容会被更改</span>
</code></pre></div><p>很多人错误的认为：在局部作用域中修改的对象会在全局作用域中反映出来，就说明
参数是按引用传递的。为了证明对象是按值传递的，看一看下面这个例子：</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> obj1 <span class="token operator">=</span> <span class="token punctuation">{</span>name<span class="token operator">:</span><span class="token string">'name1'</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token keyword">function</span> <span class="token function">setName</span><span class="token punctuation">(</span><span class="token parameter">obj</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  obj<span class="token punctuation">.</span>name <span class="token operator">=</span> <span class="token string">'name2'</span>
  obj <span class="token operator">=</span> <span class="token punctuation">{</span>name<span class="token operator">:</span><span class="token string">'new name 2333'</span><span class="token punctuation">}</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj1<span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token function">setName</span><span class="token punctuation">(</span>obj1<span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>obj1<span class="token punctuation">)</span><span class="token punctuation">;</span>  <span class="token comment">// 仍然是name2，而不是在函数内部新建的对象2333。</span>

<span class="token comment">// 这说明即使在函数内部修改了参数的值，但原始的引用仍然保持未变。</span>
<span class="token comment">// 实际上，当在函数内部重写 obj 时，这个变量引用的就是一个局部对象了。</span>
<span class="token comment">// 而这个局部对象会在函数执行完毕后立即被销毁。</span>
</code></pre></div><h3 id="检测类型"><a href="#检测类型" class="header-anchor">#</a> 检测类型</h3> <p>确定一个值是哪种<strong>基本类型</strong>可以使用<code>typeof</code>操作符，而确定一个值是哪种<strong>引用类型</strong>可以使用<code>instanceof</code>操作符。</p> <p>typeof 操作符是确定一个变量是<code>string</code>、<code>number</code>、<code>boolean</code>，还是 <code>undefined</code> 的最佳工具。</p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> num <span class="token operator">=</span> <span class="token number">10</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> str <span class="token operator">=</span> <span class="token string">'helloworld'</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> bol <span class="token operator">=</span> <span class="token boolean">true</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> nul <span class="token operator">=</span> <span class="token keyword">null</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> und <span class="token operator">=</span> <span class="token keyword">undefined</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> obj <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Object</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> reg <span class="token operator">=</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">0-9</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span>            <span class="token comment">// 正则表达式。</span>

console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> num<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">// 'number'</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> str<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">// 'string'</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> bol<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">// 'boolean'</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> nul<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">// 'object'</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> und<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">// 'undefined'</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> obj<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">// 'object'</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span><span class="token keyword">typeof</span> reg<span class="token punctuation">)</span><span class="token punctuation">;</span>    <span class="token comment">// 'object'</span>
</code></pre></div><p><code>typeof</code> 在检测引用值时用处不大，这时候你需要使用 <code>instanceof</code> 操作符。（所有引用类型值都是Object）</p> <p>语法：<code>result = variable instanceof constructor</code></p> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">var</span> persion <span class="token operator">=</span> <span class="token keyword">new</span> <span class="token class-name">Object</span><span class="token punctuation">(</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> arr <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token number">1</span><span class="token punctuation">,</span><span class="token number">2</span><span class="token punctuation">,</span><span class="token number">3</span><span class="token punctuation">,</span><span class="token number">4</span><span class="token punctuation">]</span><span class="token punctuation">;</span>
<span class="token keyword">var</span> reg <span class="token operator">=</span> <span class="token regex"><span class="token regex-delimiter">/</span><span class="token regex-source language-regex">0-9</span><span class="token regex-delimiter">/</span></span><span class="token punctuation">;</span>

console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>persion <span class="token keyword">instanceof</span> <span class="token class-name">Object</span><span class="token punctuation">)</span><span class="token punctuation">;</span>     <span class="token comment">// true</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>arr <span class="token keyword">instanceof</span> <span class="token class-name">Array</span><span class="token punctuation">)</span><span class="token punctuation">;</span>          <span class="token comment">// true</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>reg <span class="token keyword">instanceof</span> <span class="token class-name">RegExp</span><span class="token punctuation">)</span><span class="token punctuation">;</span>         <span class="token comment">// true</span>
</code></pre></div><h2 id="执行环境及作用域"><a href="#执行环境及作用域" class="header-anchor">#</a> 执行环境及作用域</h2> <p>执行环境也称作用域，执行环境分为全局执行环境和函数执行环境，没有块作用域。</p> <ul><li><strong>执行环境</strong>定义了变量或函数有权访问的其他数据，决定了他们各自的行为。</li> <li>每个执行环境都有一个与之关联的<strong>变量对象</strong>。</li> <li>在Web浏览器中，全局执行环境是<code>window</code>对象。所有全局变量和函数都是作为 window 对象的属性和方法创建的。</li> <li>某个执行环境中的所有代码执行完毕后，其本身及其内部所有变量和函数定义也全部销毁。</li> <li>当代码在一个环境中执行时，会创建变量对象的一个<strong>作用域链</strong>（scope chain）。作用域链的用途，是保证对执行环境有权访问的所有变量和函数的有序访问。</li></ul> <p>作用域链：内部环境可以通过作用域链访问所有的外部环境，但外部环境不能访问内部环境中的任何变量和函数。</p> <p><img src="/notes/assets/img/img4-3.a1319061.png" alt="image"></p> <h3 id="没有块级作用域"><a href="#没有块级作用域" class="header-anchor">#</a> 没有块级作用域！</h3> <div class="language-js extra-class"><pre class="language-js"><code><span class="token keyword">if</span> <span class="token punctuation">(</span><span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token punctuation">{</span>
  <span class="token keyword">var</span> color <span class="token operator">=</span> <span class="token string">'blue'</span><span class="token punctuation">;</span>
<span class="token punctuation">}</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>color<span class="token punctuation">)</span>  <span class="token comment">// blue</span>

<span class="token keyword">for</span> <span class="token punctuation">(</span><span class="token keyword">var</span> i<span class="token operator">=</span><span class="token number">0</span><span class="token punctuation">;</span>i<span class="token operator">&lt;</span><span class="token number">10</span><span class="token punctuation">;</span>i<span class="token operator">++</span><span class="token punctuation">)</span><span class="token punctuation">;</span>
console<span class="token punctuation">.</span><span class="token function">log</span><span class="token punctuation">(</span>i<span class="token punctuation">)</span>  <span class="token comment">// 10</span>
</code></pre></div><p>如果是在 C、C++或 Java 中，color 会在 if 语句执行完毕后被销毁。但在 JavaScript 中，if 语句中的变量声明会将变量添加到当前的执行环境（在这里是全局环境）中。</p> <p>由 for 语句创建的变量 i 即使在 for 循环执行结束后，也依旧会存在于循环外部的执行环境中。</p> <p>如果初始化变量时没有使用 var 声明，该变量会自动被添加到全局环境。</p> <p>不声明而直接初始化变量是一个常见的错误做法，因为这样可能会导致意外。在严格模式下，初始化未经声明的变量会导致错误。</p> <h2 id="垃圾收集"><a href="#垃圾收集" class="header-anchor">#</a> 垃圾收集</h2> <p>JavaScript具有自动垃圾收集机制，执行环境会负责管理代码执行过程中使用的内存。</p> <p>垃圾收集机制必须跟踪哪个变量有用哪个变量没用，对于不在有用的变量打上标记，以备将来收回其占用的内存。
标识无用变量的策略一般有两种：标记清除、引用计数。</p> <h3 id="标记清除"><a href="#标记清除" class="header-anchor">#</a> 标记清除</h3> <p>JavaScript 中最常用的垃圾收集方式是标记清除（mark-and-sweep）。当变量进入环境（例如，在函
数中声明一个变量）时，就将这个变量标记为“进入环境”。永远不能释放进入环境的变量所占用的内存，
因为只要执行流进入相应的环境，就可能会用到它们。而当变量离开环境时，则将其标记为“离开环境”。</p> <p>垃圾收集器在运行的时候会给存储在内存中的所有变量都加上标记，它会去掉<strong>环境中</strong>的变量以及被环境中
的变量引用的变量的标记。最后，垃圾收集器完成内存清除工作，销毁那些带标记的值并回收它们所占用
的内存空间。</p> <h3 id="引用计数"><a href="#引用计数" class="header-anchor">#</a> 引用计数</h3> <p>另一种不太常见的垃圾收集策略叫做<strong>引用计数</strong>（reference counting）。引用计数的含义是跟踪记录每
个值被引用的次数。
引用计数遇到了一个严重的问题：循环引用。循环引用指的是对象 A 中包含一个指向对象 B 的指针，
而对象 B 中也包含一个指向对象 A 的引用。当代码中存在循环引用现象时，“引用计数”算法就会导致问题。</p> <p>将变量设置为 null 意味着切断变量与它此前引用的值之间的连接。
IE9 把 BOM 和 DOM 对象都转换成了真正的 JavaScript 对象。</p> <h3 id="管理内存"><a href="#管理内存" class="header-anchor">#</a> 管理内存</h3> <p>由于分配给浏览器的内存数量一般比桌面程序少，我们可以通过将不用的全局变量和全局对象赋值null来释放其引用以达到释放内存的作用。
这个做法叫做<strong>解除引用</strong>（dereferencing）。解除引用的真正作用是让值脱离执行环境，以便垃圾收集器下次运行时将其回收。</p></div> <footer class="page-edit"><!----> <div class="last-updated"><span class="prefix">上次更新:</span> <span class="time">2023-4-5 17:45:19</span></div></footer> <div class="page-nav"><p class="inner"><span class="prev">
      ←
      <a href="/notes/notes/pro-js-for-web-dev-note/chapter03.html" class="prev">第3章 基本概念</a></span> <span class="next"><a href="/notes/notes/pro-js-for-web-dev-note/chapter05.html">引用类型</a>
      →
    </span></p></div> </main></div><div class="global-ui"><!----><div id="live2d-widget" class="live2d-widget-container" style="position:fixed;right:65px;bottom:0px;width:135px;height:300px;z-index:99999;opacity:0.8;pointer-events:none;"><canvas id="live2d_canvas" width="135" height="300" class="live2d_canvas" style="position:absolute;left:0px;top:0px;width:135px;height:300px;"></canvas></div></div></div>
    <script src="/notes/assets/js/app.f19b5e39.js" defer></script><script src="/notes/assets/js/2.69392339.js" defer></script><script src="/notes/assets/js/18.7dffee3a.js" defer></script><script src="/notes/assets/js/14.e376f3f7.js" defer></script>
  </body>
</html>
